﻿using System.Collections;

using Gonte.Reflection;

namespace Gonte.Workflow.Tasks
{
    /// <summary>
    /// Loops through each item and executes the task
    /// </summary>
    public class ForEach
        : GetAccessor
    {
        #region Overridables

        public override TaskResult Execute(TaskContext context)
        {
            ExceptionThrower.ThrowWhenNull("Item", _item);
            ExceptionThrower.ThrowWhenNull("Do", _do);

            TaskResult result = base.Execute(context);
            TypeAccessor typeAccessor = (TypeAccessor)result.Value;
            object data = result.AditionalValues[Data];

            IEnumerable collection = typeAccessor.GetValue(data, _property) as IEnumerable;

            foreach (object item in collection)
            {
                context.CreateLocalScope(); // Create the local scope to pass the parameters
                context.SetLocal(_item, item);

                if (!string.IsNullOrEmpty(_parent))
                {
                    context.SetLocal(_parent, data);
                }

                _do.Execute(context);

                context.DestroyLocalScope(); // Destroy the local scope
            }

            return null;
        }

        #endregion

        #region Properties

        /// <summary>
        /// The name of the parent (of the item) instance to access within the task
        /// </summary>
        public string Parent
        {
            get { return _parent; }
            set { _parent = value; }
        }

        /// <summary>
        /// The name of the item instance to access within the task
        /// </summary>
        public string Item
        {
            get { return _item; }
            set { _item = value; }
        }

        /// <summary>
        /// The task to be executed for each item
        /// </summary>
        public ITask Do
        {
            get { return _do; }
            set { _do = value; }
        }

        #endregion

        #region Fields

        private string _parent;
        private string _item;
        private ITask _do; 

        #endregion
    }
}
